home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / SoundAndMusic / cmix / lpc / track / ptrack.c < prev    next >
C/C++ Source or Header  |  1991-12-10  |  9KB  |  289 lines

  1. #define SFIRCAM
  2. /*  Main program for pitch analysis
  3.  *     The file should be mono.
  4.  *    
  5.  */
  6.  
  7. #include "sysdep.h"
  8. #include <stdio.h>
  9. #ifdef SYS5
  10. #include <fcntl.h>
  11. #endif
  12. #include <sys/file.h>
  13. #ifdef SFIRCAM
  14. #include "../../H/sfheader.h"
  15. #endif SFIRCAM
  16. #include <pwd.h>
  17. #include "crack.h"
  18. #include "ptrack.h"
  19. #include <sys/stat.h>
  20.  
  21. #include "lpsf.h"        /* INT and FLOAT #defined here */
  22. typedef short SIGTYPE;
  23. #define SAMPTYPE INT        /* shortsam-only */
  24. #define NAMESIZE 1024        /* commandline string size limit */
  25. #define FRAMAX 350
  26.  
  27. int LSLICE;
  28. int JSLIDE;
  29. float SR;
  30. float NYQ; 
  31. int JMAX;
  32. int MM;
  33. char * buildsfname();
  34. extern    int    remotein;
  35. int debug = 0, verbose=0;
  36.  
  37. float gtphi[50][5][18],gtpsi[50][6][18];    /* had to change to globals */
  38. float gtgamph[50][5],gtgamps[50][6];         /* hence the 'g' in front of the names */
  39.  
  40. main(argc, argv)
  41.      int argc;
  42.      char **argv;
  43. {
  44.     SIGTYPE sig[FRAMAX];
  45.     int MIDPOINT,needed,howmuch;
  46.     float freq[50];
  47.     float getpch(),getrms(),lowpass(), ptable();
  48.     float pchlow,pchigh,input[4];
  49.     FILE *pdata;
  50.     int i,n,jj,anal,framesize,result;
  51.     long nsamps;
  52.     float data[2],inskip,dur;
  53.     char name[NAMESIZE], *fullsfname;
  54.     char *sigp,*sigtemp;
  55.     double rmsm,freqm,rmsx,freqx;
  56.     
  57. #ifdef SFIRCAM
  58.     SFHEADER sfh;
  59.     char sfbuf[SIZEOF_BSD_HEADER], sfname[NAMESIZE];
  60.     int sfd, sfn;
  61.     int Hflag = 0;
  62.     struct stat sfst;
  63.  
  64. #endif SFIRCAM
  65.     char c;
  66.     int rflag = 0;
  67.  
  68.     /* DEFAULTS... */
  69.     *sfname = '\0';        /* '\0' => stdin */
  70.     *name = '\0';        /* '\0' => stdout */
  71.     LSLICE = 350;        /* 350 is max! */
  72.     JSLIDE = 200;
  73.     pchlow = 100.0;
  74.     pchigh = 1000.0;
  75.     inskip = 0.0;
  76.     dur = 1.0;        /* should implement an EOF dur! */
  77.     SR = 22050;
  78.  
  79.     if (debug) verbose++;
  80.     if ( (c = crack(argc, argv, "q", 1)) == 'q' ) {    /* q flag present */
  81.       verbose++;
  82.       /* query for everything, ignore any other flags */
  83.       fprintf(stderr,"Enter soundfile name : ");
  84.       scanf("%s", sfname);
  85. #ifdef SFIRCAM
  86.       fprintf(stderr,"Is soundfile headerless? (y or n) ");
  87.       scanf("%s",name); 
  88.       if ( *name == 'y' || *name == 'Y' ) {
  89.         Hflag++; fprintf(stderr,"Enter sampling rate : ");
  90.         scanf("%d",&SR); rflag++;
  91.       }
  92. #endif SFIRCAM
  93.       fprintf(stderr,"Enter output file name : ");
  94.       scanf("%s",name); 
  95.       fprintf(stderr,"Enter framesize (samples per analyzed segment) : ");
  96.       scanf("%d",&LSLICE);
  97.       fprintf(stderr,"Enter interframe offset (new samples per segment) : ");
  98.       scanf("%d",&JSLIDE); 
  99.       fprintf(stderr,"Enter low pitch estimate (cps) : ");
  100.       scanf("%f",&pchlow); 
  101.       fprintf(stderr,"Enter high pitch estimate : ");
  102.       scanf("%f",&pchigh); 
  103.       fprintf(stderr,"Enter initial skip (seconds) : ");
  104.       scanf("%f",&inskip); 
  105.       fprintf(stderr,"Enter duration of analysis (seconds) : ");
  106.       scanf("%f",&dur);
  107.       /*     and that's all     */
  108.     } 
  109.     else if ( c == EOF ) usage("-q flag takes no option");
  110.     else {            /* no q flag present */
  111.       /* set options from commandline */
  112.       arg_index = 0;    /* re-crack */
  113.       while ((c = crack(argc, argv,
  114. #ifdef SFIRCAM
  115.                 "r|h|l|f|i|s|d|o|H", 
  116. #else SFIRCAM
  117.                 "r|h|l|f|i|s|d|o|", 
  118. #endif SFIRCAM
  119.                 0)) != NULL) {
  120.         if (c == EOF) usage("error cracking commandline");
  121.         switch (c) {    /* cases w/o options */
  122. #ifdef SFIRCAM
  123.         case 'H': Hflag++; break; /* no soundfile header */
  124. #endif SFIRCAM    
  125.         default:        /* cases w/ options */
  126.           if (arg_option == NULL) usage("flag missing an option");
  127.           switch (c) {
  128.         /* sound flags... */
  129.           case 'r':        /* sampling rate */
  130.         sscanf(arg_option,"%d", &SR); rflag++; break;
  131.         /* analysis and i/o flags... */
  132.           case 'h':        /* high cps */
  133.         sscanf(arg_option,"%f", &pchigh); break; 
  134.           case 'l':        /* low cps */
  135.         sscanf(arg_option,"%f", &pchlow); break; 
  136.           case 'f':        /* framesize */
  137.         sscanf(arg_option,"%d", &LSLICE); break; 
  138.           case 'i':        /* framesize */
  139.         sscanf(arg_option,"%d", &JSLIDE); break; 
  140.           case 's':        /* skiptime */
  141.         sscanf(arg_option,"%f", &inskip); break;    
  142.           case 'd':        /* duration */
  143.         sscanf(arg_option,"%f", &dur); break; 
  144.           case 'o':        /* output filename */
  145.         if ( strlen(arg_option) >= NAMESIZE )
  146.           die("outputfile name too long!");
  147.         strcpy(name,arg_option); break; 
  148.           default: usage("unrecognized flag");
  149.           }
  150.         }
  151.       }
  152.       if ( arg_index != argc ) { /* soundfile name here */
  153.         if ( strlen(argv[arg_index]) >= NAMESIZE )
  154.           die("soundfile name too long!");
  155.         strcpy(sfname,argv[arg_index]);
  156.       }            /* else all done */
  157.     }
  158.     if ( *name == '\0' ) anal = fileno(stdout); /* write stdout */
  159.     else {
  160.       if ((anal = creat(name,0644)) < 0) /* create if not exists */
  161.         dies("ptrack: can't open output data file %s", name);
  162.     }
  163.     if ( *sfname == '\0' ) sfd = fileno(stdin); /* read stdin*/
  164.     else {
  165. //      fullsfname = buildsfname(sfname);
  166.       fullsfname = sfname;
  167. #ifdef SFREMOTE
  168.       if (index(fullsfname,':') != NULL)
  169.         sfd = rsfopen(fullsfname,'<');
  170.       else 
  171. #endif SFREMOTE
  172.         if ((sfd = open(fullsfname,O_RDONLY)) < 0)
  173.           dies("Ptrack: can't open soundfile %s",fullsfname);
  174.     }
  175.  
  176. #ifdef SFIRCAM
  177.     if ( Hflag == 0 ) {    /* use sfheader */
  178.     drwopensf(fullsfname,sfd,sfh,sfst,"ptrack",result,2);
  179.     if(result < 0) {
  180.         perror(fullsfname);
  181.         return(-1);
  182.     }
  183.       //if ((sfn = readin(sfd,sfbuf,SIZEOF_BSD_HEADER)) < SIZEOF_BSD_HEADER)
  184.        // die("Ptrack: error reading soundfile header");
  185.       //sfh = (SFHEADER *) sfbuf;
  186.       if (ismagic(&sfh)< 0)
  187.         dies("Ptrack: %s is not a soundfile",sfname);
  188.       if ( rflag == 0 ) SR = sfsrate(&sfh);
  189.     }
  190. #endif SFIRCAM
  191.     if (verbose) {
  192.       if (*name == '\0') fprintf(stderr,"Writing to <stdout>\n");
  193.       else fprintf(stderr,"Writing to %s\n",name);
  194.       if (*sfname == '\0') fprintf(stderr,"Reading from <stdin>\n");
  195.       else fprintf(stderr,"Reading from %s\n",sfname);
  196.       fprintf(stderr,"Sampling rate = %f\n",SR);
  197.       fprintf(stderr, "Pitch boundary estimates = %f (low) %f (high) \n",
  198.           pchlow,pchigh);
  199.       fprintf(stderr,"Framesize = %d\n",LSLICE);
  200.       fprintf(stderr,"Interframe offset = %d\n",JSLIDE);
  201.       fprintf(stderr,"rflag: %d Hflag: %d\n",rflag,Hflag);
  202.     }
  203.     {            /* do input skipping */
  204.       long skipbytes;
  205.       int nread;
  206.       skipbytes = (long)(inskip * SR * SAMPTYPE);
  207.       skipbytes -= skipbytes % 2;
  208.       printf("%d %f %f\n",skipbytes,inskip,SR);
  209.       if (remotein || *sfname == '\0') {
  210.         while (skipbytes > FRAMAX) { /* remote: spinread for lseek */
  211.           if ((nread = readin(sfd,(char *)sig,FRAMAX)) < FRAMAX)
  212.         die("sound skip error");
  213.           skipbytes -= nread;
  214.         }
  215.         if ((nread = readin(sfd, (char *)sig, skipbytes)) < skipbytes)
  216.           die("sound skip error");
  217.       }
  218.       else if (lseek(sfd,skipbytes,L_INCR) < 0)
  219.         die("bad sflseek on skip");
  220.     }
  221.  
  222.     NYQ = SR/2.;
  223.     JMAX = LSLICE/10;
  224.     MM = ((LSLICE/10+1)/2);
  225.     MIDPOINT = LSLICE - JSLIDE;
  226.     sigp = (char *)(sig+MIDPOINT);
  227.     ptable(pchlow,pchigh,gtphi,gtpsi,gtgamph,gtgamps,freq,n); 
  228.     if (debug) fprintf(stderr,"returned\n");
  229.  
  230.     if ((jj = readin(sfd,(char *)sig,LSLICE*SAMPTYPE)) != LSLICE*SAMPTYPE)
  231.       die("Ptrack: couldn't fill first frame");
  232.     for(i=0; i<LSLICE; i++) sig[i]=lowpass(sig[i]);
  233.     nsamps = SR * dur;
  234.     while(nsamps) {
  235.       if (debug) printf("Main loop : Nsamps = %d\n",nsamps);
  236.       data[0] = getpch(sig,gtphi,gtpsi,gtgamph,gtgamps,freq,n);
  237.       data[1] = getrms(sig);
  238.       write(anal,(char *)data,8);  
  239.       if (debug) fprintf(stderr,"pitch= %f rmsamp= %f\n ",data[0],data[1]);
  240.       sigp = (char *)(sig+MIDPOINT);
  241.       for(i=0; i<MIDPOINT; i++)  sig[i] = sig[i+JSLIDE];
  242.       howmuch=0;
  243.       needed=JSLIDE*SAMPTYPE;
  244.  
  245.       if ((howmuch=readin(sfd,sigp,needed)) != needed)
  246.         break;        /* ran up against eof */
  247.  
  248.       for(i=MIDPOINT; i<LSLICE; i++) sig[i] = lowpass(sig[i]);
  249.  
  250.       nsamps -= JSLIDE; 
  251.     }
  252. }
  253.  
  254. usage(msg)
  255.      char *msg;
  256. {
  257. #ifdef SFIRCAM
  258.   fprintf (stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
  259. #else SFIRCAM
  260.   fprintf (stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
  261. #endif SFIRCAM
  262.    "   Usage:  ptrack [flag][option] ... [soundfile]\n",
  263.    "[flag][option] from among:\n",
  264. #ifdef SFIRCAM
  265.    "-rSRATE             sampling rate of sound input (default read from\n",
  266.    "                       soundfile header; else 20000 if -H specified)\n",
  267. #else
  268.    "-rSRATE             sampling rate of sound input (default 20000)\n",
  269. #endif
  270.    "-fFRAMESIZE         analysis framesize in samples (default 350 (max))\n",
  271.    "-iINTERFRAMEOFFSET  offset in samples between frames (default 200 (250 max))\n",
  272.    "-hHIGHPITCH         high pitch estimate in cps (default 1000)\n",
  273.    "-lLOWPITCH          low pitch estimate in cps (default 100)\n",
  274.    "-sSKIPTIME          initial seconds of sound to skip over (default 0.0)\n",
  275.    "-dDURATION          duration in seconds to analyze (default 1.0)\n",
  276.    "-oOUTPUTFILE        analysis output file (stdout if absent, default)\n",
  277. #ifdef SFIRCAM
  278.    "-H                  no soundfile header, SRATE taken from -r flag\n",
  279.    "                       (default reads SRATE from soundfile header)\n",
  280. #endif
  281.    "soundfile           monaural shortsam soundfile\n",
  282.    "                       (reads shorts on stdin if absent, default)\n",
  283.    "\n",
  284.    "      or:  ptrack -q   (queries the user for commandline options)\n",
  285.    "see also:  man ptrack\n\n"
  286.    );
  287.        die(msg);
  288. }
  289.